package com.github.cdisk.xtrans.ui.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import com.github.cdisk.xtrans.annotiation.Attribute;
import com.github.cdisk.xtrans.core.BaseComponent;

/**
 * 元件属性编辑
 * @author Cdisk
 *
 */
public class ComponentReflect {

	/**
	 * 给元件对象设置属性值
	 * @param fieldName
	 * @param value
	 */
	public static void SetValue(BaseComponent component, String fieldName, Object value) {
		Field field = null;
		Class<?> clazz = component.getClass();
		for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
			Field[] fields = clazz.getDeclaredFields();
			for (Field f : fields) {
				if (f.getName().equals(fieldName)) {
					field = f;
					break;
				}
			}
			if (field != null) break;
		}
		field.setAccessible(true);
		try {
			field.set(component, value);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取元件属性列表
	 * @param component
	 * @return
	 */
	public static List<Field> GetAttribute(BaseComponent component) {
		List<Field> fieldList = new ArrayList<>();
		Class<?> clazz = component.getClass();
		for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
			Field[] fields = clazz.getDeclaredFields();
			for (int i = fields.length - 1; i >= 0; i--) {
				Field field = fields[i];
				Attribute attribute = field.getAnnotation(Attribute.class);
				if (attribute == null) continue; // 不是属性，跳过
				field.setAccessible(true); // 设置属性可访问
				fieldList.add(0, field);
			}
		}
		return fieldList;
	}

	/**
	 * 获取元件引用元件的属性列表
	 * @param component
	 * @return
	 */
	public static List<Field> GetComponentAttribute(BaseComponent component) {
		List<Field> fieldList = new ArrayList<>();
		for (Field field : GetAttribute(component)) {
			if (field.getType().isAssignableFrom(BaseComponent.class)) continue;
			fieldList.add(field);
		}
		return fieldList;
	}

	/**
	 * 清除元件引用
	 * @param component
	 * @return
	 */
	public static List<Field> RemoveComponentQuote(BaseComponent component, BaseComponent quote) {
		List<Field> fieldList = new ArrayList<>();
		for (Field field : GetAttribute(component)) {
			try {
				if (field.get(component) == quote) {
					field.set(component, null);
				}
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return fieldList;
	}

}
